package part17;

import java.util.Iterator;
import java.util.LinkedHashMap;

/**
 * @author wcj
 * @Date 2021/6/1 16:38
 * @Version 1.0
 */
public class Part173 {

    public static void main(String[] args) {
        System.out.println(MapData.map(new Letters(), 11));
    }
}

class Letters implements Generator<Pair<Integer, String>>, Iterable<Integer> {
    private int size = 9;
    private int number = 1;
    private char letter = 'A';

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            @Override
            public boolean hasNext() {
                return number < size;
            }

            @Override
            public Integer next() {
                return number++;
            }
        };
    }

    @Override
    public Pair<Integer, String> next() {
        return new Pair<Integer, String>(number++, "" + letter++);
    }
}

class Pair<K, V> {
    public final K key;
    public final V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }
}

/**
 * Map的生成器，可以创建任何类型的键值对形式，通过传递参数直接生成，而无需一个一个的添加
 *
 * @param <K>
 * @param <V>
 */
class MapData<K, V> extends LinkedHashMap<K, V> {

    public MapData(Generator<Pair<K, V>> gen, int size) {
        for (int i = 0; i < size; i++) {
            Pair<K, V> pair = gen.next();
            this.put(pair.key, pair.value);
        }
    }

    public MapData(Generator<K> genK, Generator<V> genV, int size) {
        for (int i = 0; i < size; i++) {
            this.put(genK.next(), genV.next());
        }
    }

    public MapData(Generator<K> genK, V value, int size) {
        for (int i = 0; i < size; i++) {
            this.put(genK.next(), value);
        }
    }

    public MapData(Iterable<K> genK, V value) {
        for (K k : genK) {
            this.put(k, value);
        }
    }

    public MapData(Iterable<K> genK, Generator<V> genV) {
        for (K k : genK) {
            this.put(k, genV.next());
        }
    }

    /**
     * 由一个泛型类产生key-value键值对象
     *
     * @param gen
     * @param size
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> MapData<K, V> map(Generator<Pair<K, V>> gen, int size) {
        return new MapData<K, V>(gen, size);
    }

    /**
     * 由生成器分别产生键和值
     *
     * @param genK
     * @param genV
     * @param size
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> MapData<K, V> map(Generator<K> genK, Generator<V> genV, int size) {
        return new MapData<K, V>(genK, genV, size);
    }

    /**
     * 由生成器产生键，值是固定的
     *
     * @param genK
     * @param value
     * @param size
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> MapData<K, V> map(Generator<K> genK, V value, int size) {
        return new MapData<K, V>(genK, value, size);
    }

    /**
     * 由生成器产生值，键为迭代器的值
     *
     * @param genK
     * @param genV
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> MapData<K, V> map(Iterable<K> genK, Generator<V> genV) {
        return new MapData<K, V>(genK, genV);
    }

    /**
     * 键为迭代器的值，值为固定的值
     *
     * @param genK
     * @param value
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> MapData<K, V> map(Iterable<K> genK, V value) {
        return new MapData<K, V>(genK, value);
    }
}
